﻿using UnityEngine;
using System.Collections;
using UnityEditor;
using System;

namespace Hont.HyperWigglePackage.Editor
{
    public class Adjustment : BaseWigglePlugins
    {
        bool mSelectionPX = true;
        bool mSelectionPY = true;
        bool mSelectionPZ = true;
        bool mSelectionRX = true;
        bool mSelectionRY = true;
        bool mSelectionRZ = true;

        bool mEnableCurve;
        AnimationCurve mCurve;
        bool mEnableScale;

        float mScaleValue;

        bool mEnableSmooth;
        float mSmooth;
        PRPair[] mCacheData;
        Camera mCamera;

        Vector3 mCameraCachePosition;
        Quaternion mCameraCacheRotation;


        public override void Execute(HyperWiggleEditorCore core)
        {
            base.Execute(core);

            mCamera = mCore.View.PreviewRenderUtility.camera;

            mCameraCachePosition = mCamera.transform.position;
            mCameraCacheRotation = mCamera.transform.rotation;

            mCurve = new AnimationCurve(new Keyframe(0, 0), new Keyframe(0.5f, 1), new Keyframe(1, 0));
            mScaleValue = 1;
        }

        protected override void OnExit()
        {
            mCore.IsStopCameraControl = false;
        }

        protected override void OnGUI()
        {
            GUILayout.BeginVertical(GUI.skin.box);
            GUILayout.BeginHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("px", GUILayout.Width(20));
            mSelectionPX = EditorGUILayout.Toggle(mSelectionPX);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("py", GUILayout.Width(20));
            mSelectionPY = EditorGUILayout.Toggle(mSelectionPY);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("pz", GUILayout.Width(20));
            mSelectionPZ = EditorGUILayout.Toggle(mSelectionPZ);
            GUILayout.EndHorizontal();

            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("rx", GUILayout.Width(20));
            mSelectionRX = EditorGUILayout.Toggle(mSelectionRX);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("rx", GUILayout.Width(20));
            mSelectionRY = EditorGUILayout.Toggle(mSelectionRY);
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("rx", GUILayout.Width(20));
            mSelectionRZ = EditorGUILayout.Toggle(mSelectionRZ);
            GUILayout.EndHorizontal();

            GUILayout.EndHorizontal();
            GUILayout.EndVertical();

            GUILayout.BeginVertical(GUI.skin.box);
            mEnableCurve = EditorGUILayout.Toggle("Enable Curve", mEnableCurve);
            mCurve = EditorGUILayout.CurveField("Curve:", mCurve);
            GUILayout.EndVertical();

            GUILayout.BeginVertical(GUI.skin.box);
            mEnableScale = EditorGUILayout.Toggle("Enable Scale", mEnableScale);
            mScaleValue = EditorGUILayout.Slider("Scale: ", mScaleValue, -10f, 10f);
            GUILayout.EndVertical();

            GUILayout.BeginVertical(GUI.skin.box);
            mEnableSmooth = EditorGUILayout.Toggle("Enable Smooth", mEnableSmooth);
            mSmooth = EditorGUILayout.Slider("Smooth: ", mSmooth, 0f, 1f);
            GUILayout.EndVertical();

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Cancel"))
            {
                mCamera.transform.position = mCameraCachePosition;
                mCamera.transform.rotation = mCameraCacheRotation;

                if (mCacheData != null)
                    mCacheData.CopyTo(mCore.FrameData, 0);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
            }

            if (GUILayout.Button("Apply"))
            {
                mCacheData = new PRPair[mCore.FrameData.Length];
                mCore.FrameData.CopyTo(mCacheData, 0);

                for (int i = 0; i < mCore.FrameData.Length; i++)
                {
                    var item = mCore.FrameData[i];
                    var mulNumber = mScaleValue;
                    var smooth = mSmooth;

                    if (mEnableCurve)
                    {
                        var current = i / (float)mCore.EndFrame;
                        var curveValue = mCurve.Evaluate(current);
                        mulNumber = mulNumber * curveValue;
                        smooth = smooth * curveValue;
                    }

                    if (mEnableScale)
                    {
                        if (mSelectionPX)
                            item.RelativePosition.x *= mScaleValue;

                        if (mSelectionPY)
                            item.RelativePosition.y *= mScaleValue;

                        if (mSelectionPZ)
                            item.RelativePosition.z *= mScaleValue;

                        if (mSelectionRX)
                            item.RelativeRotation.x *= mScaleValue;

                        if (mSelectionRY)
                            item.RelativeRotation.y *= mScaleValue;

                        if (mSelectionRZ)
                            item.RelativeRotation.z *= mScaleValue;
                    }

                    if (mEnableSmooth)
                    {
                        if (i > 0)
                        {
                            var prev = mCore.FrameData[i - 1];
                            var smoothP = Vector3.Lerp(item.RelativePosition, prev.RelativePosition, smooth);
                            var smoothR = Vector3.Lerp(item.RelativeRotation, prev.RelativeRotation, smooth);

                            if (mSelectionPX)
                                item.RelativePosition.x = smoothP.x;

                            if (mSelectionPY)
                                item.RelativePosition.y = smoothP.y;

                            if (mSelectionPZ)
                                item.RelativePosition.z = smoothP.z;

                            if (mSelectionRX)
                                item.RelativeRotation.x = smoothR.x;

                            if (mSelectionRY)
                                item.RelativeRotation.y = smoothR.y;

                            if (mSelectionRZ)
                                item.RelativeRotation.z = smoothR.z;
                        }
                    }

                    mCore.FrameData[i] = item;
                }

                HyperWiggleUtil.StableOffset(mCore.FrameData);

                mCore.UpdatePreview();
                mCore.UpdateTimeline();
            }

            GUILayout.EndHorizontal();
        }
    }
}